package com.ruicar.afs.cloud.workflow.greatwall.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.query.QueryCondition;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.workflow.api.enums.FlowStatus;
import com.ruicar.afs.cloud.workflow.api.util.FlowMappingHelper;
import com.ruicar.afs.cloud.workflow.greatwall.dto.exception.FlowExceptionDto;
import com.ruicar.afs.cloud.workflow.greatwall.entity.AfsGreatWallWorkflowBizData;
import com.ruicar.afs.cloud.workflow.greatwall.entity.AfsGreatWallWorkflowNoticeException;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtMsgType;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtObjectCode;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowBizDataService;
import com.ruicar.afs.cloud.workflow.greatwall.service.AfsGreatWallWorkflowNoticeExceptionService;
import com.ruicar.afs.cloud.workflow.api.vo.FlowStatusVO;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.ruicar.afs.cloud.workflow.api.constant.FlowConstant.FLOW_EXCEPTION_DESC_KEY;

@RestController
@RequestMapping("/flowException")
@AllArgsConstructor
public class AfsGreatWallWorkFLowExceptionController {
    private final AfsGreatWallWorkflowNoticeExceptionService afsGreatWallWorkflowNoticeExceptionService;
    private final AfsGreatWallWorkflowBizDataService afsGreatWallWorkflowBizDataService;
    @PostMapping("/list")
    public IResponse<Page<FlowExceptionDto>> listException(@RequestBody QueryCondition<FlowExceptionDto> queryCondition) {
        LambdaQueryWrapper<AfsGreatWallWorkflowNoticeException> queryWrappers =
                Wrappers.<AfsGreatWallWorkflowNoticeException>lambdaQuery()
                        .eq(StringUtils.isNotBlank(queryCondition.getCondition().getAfsFlowKey()), AfsGreatWallWorkflowNoticeException::getFlowInstanceId, StringUtils.isNotBlank(queryCondition.getCondition().getAfsFlowKey()) ? FlowMappingHelper.getServiceId(queryCondition.getCondition().getAfsFlowKey()) : "")
                        .eq(StringUtils.isNotBlank(queryCondition.getCondition().getBizDataId()), AfsGreatWallWorkflowNoticeException::getBizDataId, queryCondition.getCondition().getBizDataId())
                        .orderByAsc(AfsGreatWallWorkflowNoticeException::getId);
        ;
        Page<AfsGreatWallWorkflowNoticeException> pageQuery =
                afsGreatWallWorkflowNoticeExceptionService.page(queryCondition.page(), queryWrappers);

        IPage<FlowExceptionDto> flowExceptionDtoPage = pageQuery.convert(e -> {
            FlowExceptionDto flowExceptionDto = new FlowExceptionDto();
            flowExceptionDto.setId(e.getId());
            flowExceptionDto.setAfsFlowKey(FlowMappingHelper.getAfsKey(e.getFlowServiceId()));
            flowExceptionDto.setBizDataId(e.getBizDataId());
            flowExceptionDto.setFlowInstanceId(e.getFlowInstanceId());
            flowExceptionDto.setNoticeInfo(e.getNoticeInfo());
            flowExceptionDto.setServiceId(e.getFlowServiceId());
            String[] noticeTypes = e.getNoticeType().split("-");
            flowExceptionDto.setGwtMsgType((GwtMsgType) AfsEnumUtil.getEnum(noticeTypes[0], GwtMsgType.class));
            flowExceptionDto.setGwtMsgTypeName(AfsEnumUtil.desc(flowExceptionDto.getGwtMsgType()));
            flowExceptionDto.setGwtObjectCode((GwtObjectCode) AfsEnumUtil.getEnum(noticeTypes[1], GwtObjectCode.class));
            flowExceptionDto.setGwtObjectCodeName(AfsEnumUtil.desc(flowExceptionDto.getGwtObjectCode()));
            return flowExceptionDto;
        });

        return IResponse.success(flowExceptionDtoPage);
    }

    @PostMapping("/resolverException")
    @Transactional(rollbackFor = Exception.class)
    public IResponse<Boolean> resolverException(@RequestBody FlowExceptionDto flowExceptionDto) {
       return IResponse.success(afsGreatWallWorkflowNoticeExceptionService.resolverException(flowExceptionDto,false));
    }
    @PostMapping("/queryFlowStatus")
    public IResponse<List<FlowStatusVO>> queryFlowStatusByFlowInstanceIds(@RequestParam String flowInstanceIds){
        if(flowInstanceIds.length()>0) {
            List<FlowStatusVO> flowStatusVOS =  afsGreatWallWorkflowBizDataService
                    .list(Wrappers.<AfsGreatWallWorkflowBizData>lambdaQuery().in(AfsGreatWallWorkflowBizData::getFlowInstanceId, Arrays.asList(flowInstanceIds.split(","))))
                    .stream().map(bizdate->{
                        FlowStatusVO flowStatusVO = new FlowStatusVO();
                        flowStatusVO.setFlowInstanceId(bizdate.getFlowInstanceId());
                        flowStatusVO.setFlowStatus(bizdate.getFlowStatus());
                        flowStatusVO.setFlowStatusDesc(AfsEnumUtil.desc(bizdate.getFlowStatus()));
                        flowStatusVO.setBizDataId(bizdate.getBizDataId());
                        if(bizdate.getFlowStatus()== FlowStatus.ERROR) {
                            String bizData = bizdate.getBizData();
                            if (org.apache.commons.lang3.StringUtils.isNotEmpty(bizData)) {
                                JSONObject bizDataJson = JSONObject.parseObject(bizData);
                                flowStatusVO.setExceptionDesc(bizDataJson.getString(FLOW_EXCEPTION_DESC_KEY));
                            } else {
                                flowStatusVO.setFlowStatusDesc("未知");
                            }
                        }
                        flowStatusVO.setFlowTemplateName(FlowMappingHelper.getFlowMapping(bizdate.getFlowServiceId()).getFlowName());
                        return flowStatusVO;
                    }).collect(Collectors.toList());
            return IResponse.success(flowStatusVOS);
        }
        return IResponse.success(new ArrayList<>());
    }
}
